/*
	The MIT License

	Copyright (c) 2010 IFMO/GameDev Studio

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.
*/


#pragma once

/*-----------------------------------------------------------------------------
	Scene light stuff :
-----------------------------------------------------------------------------*/

class ERScene;


class	ERSLightRenderer : public ICoreObject {
	public:
						ERSLightRenderer		( ERScene *scene );
						~ERSLightRenderer		( void );

		//	public stuff :						
		void			SetAmbientLevel				( const EVec4 &color );
		void			ReloadShaders				( void );
		
		void			SetView						( const EMatrix4 &view, const EMatrix4 &proj, const EVec4 &view_pos );
		void			SetLight					( const ERendLightDesc_s *light );
		void			SetLightPose				( const EVec4 &pos, const EQuat &orient );
		void			SetShadowMapViewProj		( const EMatrix4 &vp );
		
		//	interneal public stuff :
		void			BeginStencilMarking			( void );
		void			BeginDrawingAgainstStencil	( void );
		void			EndStencilDrawing			( void );
		
		void			DrawOmniLightShape			( float radius );
		void			DrawSpotLightShape			( float radius, float spot_radius );
		
		void			CopyDepthBuffer				( void );
		void			RenderAmbient				( IPxTexture target );
		void			RenderLighting				( IPxTexture target );
		
		IPxTexture		GetSMDepth					( void ) { return sm_depth; }
		IPxTexture		GetSMColor					( void ) { return sm_color; }

		void			SetGBuffer					( IPxTexture *gbuffer, IPxTexture gbuffer_depth );
		void			SetupGBufferSamplers		( void );
	

	public:
		ERScene	*scene;
		IPxRTManager	rtm;
		IPxTXManager	txm;
		
		ID3DXEffect	*effect;
		D3DXHANDLE	tech_copy_depth;
		D3DXHANDLE	tech_ambient;
		D3DXHANDLE	tech_light;

		IPxVar		rs_white_diffuse;		
		IPxVar		rs_skip_diffuse;
		IPxVar		rs_skip_specular;
		IPxVar		rs_skip_lighting;
		
	protected:
		IPxTexture	gbuffer[4];
		IPxTexture	gbuffer_depth;
	
		IPxTexture	sm_depth;
		IPxTexture	sm_color;
	};
	
	

class	ERSLight : public IRSLight {
	public:
						ERSLight		( ERScene *scene, const ERendLightDesc_s *light_desc );
						~ERSLight		( void );
		
		virtual void	SetPose				( const EVec4 &position, const EQuat &orient );
		virtual void	GetPose				( EVec4 &position, EQuat &orient ) const;
		virtual void	SetVelocity			( const EVec4 &linear_velocity ) {}
		virtual void	GetVelocity			( EVec4 &linear_velocity ) const {}
						
		virtual void	UpdateLight			( const ERendLightDesc_s *light_desc );
		virtual void	SetColor			( const EVec4 &color );
		virtual void	SetRadius			( float radius );
		virtual void	SetVisible			( bool visible );
		
		void			RenderLight			( IPxTexture target );
		
	protected:
		void			RenderOmniLight		( IPxTexture target );
		void			RenderSpotLight		( IPxTexture target );
		void			RenderSpotLightSM	( IPxTexture target, const EVec4 &pos, const EQuat &orient );
	
		void			DebugOmniShape		( void );
		void			DebugSpotShape		( void );
		
		bool			is_visible;
	
		ERScene	*scene;
		IPxRTManager		rtm;
		ERendLightDesc_s	light_desc;
		hard_ref<ERSLightRenderer>	light_rend;
		IPxTexture			mask;
	};
